package com.dxtx.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.TextView;

import com.dxtx.common.R;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by user on 2016/9/20.
 */
public class GuestrueView extends TextView {
    private static final String tag = "px";

    private int mWidth, mHeight;
    private Paint paint, ringPaint, linePaint, errorLinePaint;

    private float ringRange;

    private List<Point> points = new ArrayList<Point>();

    private List<Point> selectPoints = new ArrayList<Point>();

    private Bitmap sBitmap, uBitmap, eBitmap;
    Rect sRect, uRect, eRect;
    private int itemSelected = R.drawable.icon_select;
    private int itemUnSelected = R.drawable.icon_unselect;
    private int itemError = R.drawable.icon_error;

    // 开始绘制手势


    private boolean start = false;
    private boolean error = false;
    // 连接线颜色

    private int lineColor = getResources().getColor(R.color.colorPrimary);
    private int lineErrorColor = getResources().getColor(R.color.guestrue_error);

    public GuestrueView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public GuestrueView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GuestrueView(Context context) {
        super(context);
        init();
    }

    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.GRAY);
        ringPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        ringPaint.setColor(Color.RED);
        // ringPaint.setStrokeWidth(20);


        // ringPaint.setStyle(Paint.Style.STROKE);

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(lineColor);
        linePaint.setStrokeWidth(getResources().getDimension(R.dimen.line));
        linePaint.setStyle(Paint.Style.STROKE);

        //错误的画笔
        errorLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        errorLinePaint.setColor(lineErrorColor);
        errorLinePaint.setStrokeWidth(getResources().getDimension(R.dimen.line));
        errorLinePaint.setStyle(Paint.Style.STROKE);

        sBitmap = BitmapFactory.decodeResource(getResources(), itemSelected);
        uBitmap = BitmapFactory.decodeResource(getResources(), itemUnSelected);
        eBitmap = BitmapFactory.decodeResource(getResources(), itemError);
        sRect = new Rect(0, 0, sBitmap.getWidth(), sBitmap.getHeight());
        uRect = new Rect(0, 0, uBitmap.getWidth(), uBitmap.getHeight());
        eRect = new Rect(0, 0, eBitmap.getWidth(), eBitmap.getHeight());

    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getMesureSize(widthMeasureSpec), getMesureSize(widthMeasureSpec));
        mWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        mHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
        if (mWidth <= 0 || mHeight <= 0 || !points.isEmpty()) {
            return;
        }
        points.clear();
        for (int j = 0; j < 3; j++) {
            for (int i = 0; i < 3; i++) {
                Point point = new Point(mWidth / 3 * i + mWidth / 6, mHeight / 3 * j + mHeight / 6);
                points.add(point);
            }
        }
        ringRange = Math.min(mWidth, mHeight) / 12;
    }

    public int getMesureSize(int measure) {
        switch (MeasureSpec.getMode(measure)) {
            case MeasureSpec.EXACTLY:
                return MeasureSpec.getSize(measure);
            default:
                return 0;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (selectPoints.size() > 1) {
            int size = selectPoints.size();
            for (int i = 0; i < size; i++) {
                Point p = selectPoints.get(i);
                // 画连接线
                if (i < size - 1) {
                    Point n = selectPoints.get(i + 1);
                    canvas.drawLine(p.x, p.y, n.x, n.y, error ? errorLinePaint : linePaint);
                }
            }
        }
        if (!error && !selectPoints.isEmpty() && start && c != null) {
            // 从最后一个到当前触摸点的连线
            Point p = selectPoints.get(selectPoints.size() - 1);
            canvas.drawLine(p.x, p.y, c.x, c.y, linePaint);
        }
        for (Point p : points) {
            RectF dst = new RectF(p.x - ringRange, p.y - ringRange, p.x + ringRange, p.y + ringRange);
            if (selectPoints.contains(p)) {
                if (!error) {
                    // 画选中的圆环
                    canvas.drawBitmap(sBitmap, sRect, dst, null);
                } else {
                    canvas.drawBitmap(eBitmap, eRect, dst, null);
                }
            } else {
                // 画未选中的圆
                canvas.drawBitmap(uBitmap, uRect, dst, null);
            }
        }
    }

    private Point c;

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (error) {
                    return false;
                }
                Point p = eventNearPoint(e);
                if (p == null) {
                    break;
                }
                if (!selectPoints.isEmpty()) {
                    selectPoints.clear();
                }
                start = true;
                selectPoints.add(p);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                Point pm = eventNearPoint(e);
                if (pm == null || selectPoints.contains(pm)) {
                    if (start) {
                        c = new Point((int) e.getX(), (int) e.getY());
                        invalidate();
                    }
                    break;
                }
                if (!start) {
                    start = true;
                }
                selectPoints.add(pm);
                invalidate();
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (!selectPoints.isEmpty() && guestrueListener != null) {
                    guestrueListener.onGuestrue(getNumString());
                }
                start = false;
                c = null;
                break;
            default:
                break;
        }
        return true;
    }

    private Point eventNearPoint(MotionEvent e) {
        for (Point p : points) {
            float distance = (p.x - e.getX()) * (p.x - e.getX()) + (p.y - e.getY()) * (p.y - e.getY());
            if (distance < ringRange * ringRange) {
                return p;
            }
        }

        return null;
    }

    public void clear() {
        selectPoints.clear();
        invalidate();
    }

    public void error(long delay) {
        error = true;
        invalidate();
        handler.sendEmptyMessageDelayed(0x123, delay);
    }

    private android.os.Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0x123) {
                error = false;
                clear();
            }
        }
    };

    public String getNumString() {
        StringBuffer sb = new StringBuffer();
        for (Point p : selectPoints) {
            sb.append(points.indexOf(p) + 1);
        }
        return sb.toString();
    }

    public void setLineColor(int lineColor) {
        this.lineColor = lineColor;
        linePaint.setColor(lineColor);
    }

    public void setDrawableResource(int itemSelected, int itemUnSelected, int itemError) {
        sBitmap = BitmapFactory.decodeResource(getResources(), itemSelected);
        uBitmap = BitmapFactory.decodeResource(getResources(), itemUnSelected);
        eBitmap = BitmapFactory.decodeResource(getResources(), itemError);
        sRect = new Rect(0, 0, sBitmap.getWidth(), sBitmap.getHeight());
        uRect = new Rect(0, 0, uBitmap.getWidth(), uBitmap.getHeight());
        eRect = new Rect(0, 0, eBitmap.getWidth(), eBitmap.getHeight());
    }

    private OnGuestrueListener guestrueListener;

    public interface OnGuestrueListener {
        void onGuestrue(String pass);
    }

    public void setOnGuestrueListener(OnGuestrueListener guestrueListener) {
        this.guestrueListener = guestrueListener;
    }

    public void setNumString(String numString) {
        selectPoints.clear();
        for (int i = 0; i < numString.length(); i++) {
            int index = Integer.parseInt(numString.substring(i, i + 1));
            selectPoints.add(points.get(index - 1));
        }
        invalidate();
    }
}
